package com.ssy.lingxi.after.sale.serviceimpl;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.after.sale.entity.QRepairGoodsDetailAssociatedDO;
import com.ssy.lingxi.after.sale.entity.QRepairGoodsDetailDO;
import com.ssy.lingxi.after.sale.entity.RepairGoodsDO;
import com.ssy.lingxi.after.sale.entity.RepairGoodsDetailDO;
import com.ssy.lingxi.after.sale.model.vo.request.RepairGoodsDetailPageVO;
import com.ssy.lingxi.after.sale.model.vo.response.RepairGoodsDetailQueryVO;
import com.ssy.lingxi.after.sale.repository.RepairGoodsDetailRepository;
import com.ssy.lingxi.after.sale.repository.RepairGoodsRepository;
import com.ssy.lingxi.after.sale.service.IRepairGoodsDetailService;
import com.ssy.lingxi.after.sale.utils.ParamVerifyUtils;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.Wrapper;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 售后维修货物接口服务实现
 * @author 伍将
 * @date 2020/9/8
 * @version 2.0.0
 */
@Service
public class RepairGoodsDetailServiceImpl implements IRepairGoodsDetailService {

    @Resource
    private RepairGoodsDetailRepository repairGoodsDetailRepository;
    @Resource
    private RepairGoodsRepository repairGoodsRepository;
    @Resource
    private JPAQueryFactory jpaQueryFactory;

    /**
     * 分页查询维修货物
     * @author 伍将
     * @date 2020/9/8
     * @param pageVO:
     * @return com.ssy.lingxi.common.response.Wrapper<com.ssy.lingxi.common.response.PageData < com.ssy.lingxi.after.sale.model.vo.response.RepairGoodsQueryVO>>
     **/
    @Override
    public Wrapper<PageData<RepairGoodsDetailQueryVO>> pageList(RepairGoodsDetailPageVO pageVO) {
        RepairGoodsDO repairGoodsDO = repairGoodsRepository.findById(pageVO.getRepairId()).orElse(null);
        if(repairGoodsDO==null){
            return Wrapper.success(new PageData<>(0L, null));
        }
        PageData<RepairGoodsDetailQueryVO> pageData;
        if(ParamVerifyUtils.isContractOrderType(repairGoodsDO.getOrderType())){//合同订单类型（询价、竞价、招标合同）
            pageData=pageMaterielList(pageVO);
        }else{
            pageData=pageProductList(pageVO);
        }
        return Wrapper.success(pageData);
    }

    private PageData<RepairGoodsDetailQueryVO> pageProductList(RepairGoodsDetailPageVO pageVO){
        // step 1: 组装查询条件
        Specification<RepairGoodsDetailDO> spec =  (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("repairId").as(Long.class), pageVO.getRepairId()));
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        // step 2: 组装分页参数
        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").descending());

        // step 3: 分页查询数据
        Page<RepairGoodsDetailDO> result = this.repairGoodsDetailRepository.findAll(spec, page);

        // step 4: 组装返回数据
        List<RepairGoodsDetailQueryVO> resultList = result.getContent().stream().map(r -> {
            RepairGoodsDetailQueryVO queryVO = new RepairGoodsDetailQueryVO();
            queryVO.setOrderId(r.getOrderId());
            queryVO.setOrderRecordId(r.getOrderRecordId());
            queryVO.setOrderNo(r.getOrderNo());
            queryVO.setProductId(r.getProductId());
            queryVO.setProductName(r.getProductName());
            queryVO.setCategory(r.getCategory());
            queryVO.setBrand(r.getBrand());
            queryVO.setUnit(r.getUnit());
            queryVO.setPurchaseCount(r.getPurchaseCount());
            queryVO.setRepairCount(r.getRepairCount());
            queryVO.setRepairReason(r.getRepairReason());
            queryVO.setIsHasTax(r.getIsHasTax());
            queryVO.setTaxRate(r.getTaxRate());
            queryVO.setContractId(r.getContractId());
            queryVO.setContractNo(r.getContractNo());
            queryVO.setSkuPic(r.getSkuPic());
            return queryVO;
        }).collect(Collectors.toList());

        return new PageData<>(result.getTotalElements(), resultList);
    }

    /**
     * 查询合同相关的维修物料信息
     * @param pageVO 分页查询条件
     * @return 合同相关的维修物料信息
     */
    private PageData<RepairGoodsDetailQueryVO> pageMaterielList(RepairGoodsDetailPageVO pageVO){
        // 查询表实体
        QRepairGoodsDetailDO repairGoodsDetailDO = QRepairGoodsDetailDO.repairGoodsDetailDO;
        QRepairGoodsDetailAssociatedDO repairGoodsDetailMaterielDO=QRepairGoodsDetailAssociatedDO.repairGoodsDetailAssociatedDO;
        // 查询条件构造
        BooleanBuilder predicates = new BooleanBuilder();
        predicates.and(repairGoodsDetailDO.repairId.eq(pageVO.getRepairId()));
        // 关联查询
        JPAQuery<RepairGoodsDetailQueryVO> query = jpaQueryFactory
                .select(Projections.bean(RepairGoodsDetailQueryVO.class,
                        repairGoodsDetailDO.orderId,
                        repairGoodsDetailDO.orderRecordId,
                        repairGoodsDetailDO.orderNo,
                        repairGoodsDetailDO.productId,
                        repairGoodsDetailDO.productName,
                        repairGoodsDetailDO.type,
                        repairGoodsDetailDO.category,
                        repairGoodsDetailDO.brand,
                        repairGoodsDetailDO.unit,
                        repairGoodsDetailDO.skuPic,
                        repairGoodsDetailDO.purchaseCount,
                        repairGoodsDetailDO.repairCount,
                        repairGoodsDetailDO.repairReason,
                        repairGoodsDetailDO.isHasTax,
                        repairGoodsDetailDO.taxRate,
                        repairGoodsDetailDO.contractId,
                        repairGoodsDetailDO.contractNo,
                        repairGoodsDetailMaterielDO.productId.as("associatedProductId"),
                        repairGoodsDetailMaterielDO.productName.as("associatedProductName"),
                        repairGoodsDetailMaterielDO.brand.as("associatedBrand"),
                        repairGoodsDetailMaterielDO.category.as("associatedCategory"),
                        repairGoodsDetailMaterielDO.unit.as("associatedUnit"),
                        repairGoodsDetailMaterielDO.type.as("associatedType"))
                )
                .from(repairGoodsDetailMaterielDO)
                .leftJoin(repairGoodsDetailDO)
                .on(repairGoodsDetailMaterielDO.repairDetailId.eq(repairGoodsDetailDO.id))
                .where(predicates);

        long totalCount = query.fetchCount();
        List<RepairGoodsDetailQueryVO> responses = query.orderBy(repairGoodsDetailMaterielDO.id.desc())
                .offset(pageVO.getCurrentOffset())
                .limit(pageVO.getPageSize())
                .fetch();
        return new PageData<>(totalCount, responses);
    }
}
